(function(){
  /**
   * line 的格式为{startXY:[],endXY:[],lineWidth:2,orientation:0,lineStyle:0,hasBeginArrows:false,hasEndArrows:true}
   * 
   */
  var svg_line = window.SvgLine = function(options){
    this.container = options.targetElement;   // 目标元素 svg要插入的目标元素对象
    this.lines = options.lines;                   // 线条数组
    this.lineStyle=options.lineStyle;             // 0 直线  1 断点  2 断线  3 长线
    this.lineOrientation=options.lineOrientation; // 0 水平  1 垂直 
    this.hasBeginArrows=options.hasBeginArrows;      // 是否有开始箭头
    this.hasEndArrows=options.hasEndArrows;          // 是否有结束箭头
    this.lineColor=options.lineColor;             // 线条开始颜色
    this.lineGradientColor=options.lineGradientColor; // 线条渐变时的结束颜色
    this.lineWidth=options.lineWidth;             // 默认线条宽度

    if(this.lineGradientColor==undefined){
      this.lineGradientColor = this.lineColor;
    }
    
    removeChildrenElements(this.container,".svg-line");
    var svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
    svg.classList.add("svg-line");
    this.svg = svg;
    this.container.appendChild(svg);
  }

  svg_line.prototype.setLines=function(lines){
    this.lines=lines;
    this.render();
  };
  svg_line.prototype.setOptions=function(options){
    this.container = options.targetElement;   // 目标元素 svg要插入的目标元素对象
    this.lines = options.lines;                   // 线条数组
    this.lineStyle=options.lineStyle;             // 0 直线  1 断点  2 断线  3 长线
    this.lineOrientation=options.lineOrientation; // 0 水平  1 垂直 
    this.hasBeginArrows=options.hasBeginArrows;      // 是否有开始箭头
    this.hasEndArrows=options.hasEndArrows;          // 是否有结束箭头
    this.lineColor=options.lineColor;             // 线条开始颜色
    this.lineGradientColor=options.lineGradientColor; // 线条渐变时的结束颜色
    this.lineWidth=options.lineWidth;             // 默认线条宽度

    if(this.lineGradientColor==undefined){
      this.lineGradientColor = this.lineColor;
    }
  };
  svg_line.prototype.render=function(){
    var me = this;
    // removeChildrenElements(this.container,".svg-line");
    // var svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
    // svg.classList.add("svg-line");
    svg=this.svg;
    this.svg.style.height=this.container.scrollHeight;
    this.svg.style.width=this.container.scrollWidth;
    while(this.svg.children.length>0){
      this.svg.children[0].remove();
    }
    // svg.style.width=this.container.offsetWidth+"px";
    // svg.style.height=this.container.offsetHeight+"px";
    
    /**
     * 定义后续需要用到的元素
     * 主要是箭头和渐变样式
     */
    var defs = document.createElementNS("http://www.w3.org/2000/svg","defs");
    // 定义开始箭头
    var marker_begin_arrow = document.createElementNS("http://www.w3.org/2000/svg","marker");
    marker_begin_arrow.setAttribute("id","begin_arrow");
    marker_begin_arrow.setAttribute("viewBox","0 0 10 10");
    marker_begin_arrow.setAttribute("markerWidth",10);
    marker_begin_arrow.setAttribute("markerHeight",7);
    marker_begin_arrow.setAttribute("refX",9);
    marker_begin_arrow.setAttribute("refY",3.5);
    marker_begin_arrow.setAttribute("orient","auto-start-reverse");
    var begin_arrow = document.createElementNS("http://www.w3.org/2000/svg","polygon");
    begin_arrow.setAttribute("points","0 0, 10 3.5, 0 7");
    begin_arrow.setAttribute("fill",this.lineColor||"#4facfe");
    marker_begin_arrow.appendChild(begin_arrow);
    // 定义结束箭头
    var marker_end_arrow = document.createElementNS("http://www.w3.org/2000/svg","marker");
    marker_end_arrow.setAttribute("id","end_arrow");
    marker_end_arrow.setAttribute("viewBox","0 0 10 10");
    marker_end_arrow.setAttribute("markerWidth",10);
    marker_end_arrow.setAttribute("markerHeight",7);
    marker_end_arrow.setAttribute("refX",9);
    marker_end_arrow.setAttribute("refY",3.5);
    marker_end_arrow.setAttribute("orient","auto-start-reverse");
    var end_arrow = document.createElementNS("http://www.w3.org/2000/svg","polygon");
    end_arrow.setAttribute("points","0 0, 10 3.5, 0 7");
    end_arrow.setAttribute("fill",this.lineGradientColor||"#4facfe");
    marker_end_arrow.appendChild(end_arrow);

    // 定义线条渐样式
    var linear_gradient_vertical = document.createElementNS("http://www.w3.org/2000/svg","linearGradient");
    linear_gradient_vertical.setAttribute("id","linear_gradient_vertical");
    linear_gradient_vertical.setAttribute("x1","0%");
    linear_gradient_vertical.setAttribute("y1","0%");
    linear_gradient_vertical.setAttribute("x2","0%");
    linear_gradient_vertical.setAttribute("y2","100%");  //垂直方向渐变
    // 开始样式
    var begin_style = document.createElementNS("http://www.w3.org/2000/svg","stop");
    begin_style.setAttribute("offset","0%");
    begin_style.style["stop-color"]=this.lineColor;  // 颜色
    begin_style.style["stop-opacity"]=1;        // 不透明度
    // 结束样式
    var end_style = document.createElementNS("http://www.w3.org/2000/svg","stop");
    end_style.setAttribute("offset","100%");
    end_style.style["stop-color"]=this.lineGradientColor;  // 颜色
    end_style.style["stop-opacity"]=1;   
    linear_gradient_vertical.appendChild(begin_style);
    linear_gradient_vertical.appendChild(end_style);

    var linear_gradient_horizontal = document.createElementNS("http://www.w3.org/2000/svg","linearGradient");
    linear_gradient_horizontal.setAttribute("id","linear_gradient_horizontal");
    linear_gradient_horizontal.setAttribute("x1","0%");
    linear_gradient_horizontal.setAttribute("y1","0%");
    linear_gradient_horizontal.setAttribute("x2","100%");  // 水方向线渐变
    linear_gradient_horizontal.setAttribute("y2","0%");

    // 开始样式
    begin_style = document.createElementNS("http://www.w3.org/2000/svg","stop");
    begin_style.setAttribute("offset","0%");
    begin_style.style["stop-color"]=this.lineColor;  // 颜色
    begin_style.style["stop-opacity"]=1;        // 不透明度
    // 结束样式
    end_style = document.createElementNS("http://www.w3.org/2000/svg","stop");
    end_style.setAttribute("offset","100%");
    end_style.style["stop-color"]=this.lineGradientColor;  // 颜色
    end_style.style["stop-opacity"]=1;        // 不透明度

    linear_gradient_horizontal.appendChild(begin_style);
    linear_gradient_horizontal.appendChild(end_style);

    
    defs.appendChild(marker_begin_arrow);
    defs.appendChild(marker_end_arrow);
    defs.appendChild(linear_gradient_vertical);
    defs.appendChild(linear_gradient_horizontal);
    svg.appendChild(defs);

    this.lines.forEach(line=>{
      line = createLine(line,me);
      svg.appendChild(line);
    })
  };

  function createLine(line,options){
    const x1 = line.startXY[0];
    const y1 = line.startXY[1];
    const x2 = line.endXY[0];
    const y2 = line.endXY[1];
    var line_width = options.lineWidth;
    if(line.lineWidth!=undefined) line_width = line.lineWidth;
    if(line_width==undefined) line_width = 2;

    var orientation = options.lineOrientation;
    if(line["orientation"]!=undefined) orientation=line["orientation"];    
    var d =  "M "+x1+","+y1;
    let offset_x=x2-x1;
    let offset_y=y2-y1;
    if(offset_x==0) offset_x=1; // 设置最小偏移量，防止应偏移量为0导致线条不能正常显示
    if(offset_y==0) offset_y=1;  // 设置最小偏移量，防止应偏移量为0导致线条不能正常显示
    switch(parseInt(orientation)){
      case 0:
        d+= " c "+offset_x/2+" 0, "+offset_x/2+" "+offset_y+", "+offset_x+","+offset_y
        break;
      case 1:
        d+= " c 0 "+offset_y/2+", "+offset_x+","+offset_y/2+""+" "+offset_x+","+offset_y
        break;
    }

    var lineStyle = options.lineStyle;
    if(line["lineStyle"]!=undefined) lineStyle=line["lineStyle"];
    var strokeDasharray="";
    switch(lineStyle){
      case 1:
        strokeDasharray=line_width+","+(line_width+2);
        break;
      case 2:
        strokeDasharray=line_width*2+","+(line_width*2+2);
        break;
      case 3:
        strokeDasharray=line_width*4+","+(line_width*4+2);
        break;
    }

    var svg_path = document.createElementNS("http://www.w3.org/2000/svg","path");
    svg_path.setAttribute("d",d);
    svg_path.setAttribute("stroke-dasharray",strokeDasharray);
    svg_path.style.fill="none";
    svg_path.style.stroke="url(#linear_gradient_vertical)";
    if(orientation==0){
      svg_path.style.stroke="url(#linear_gradient_horizontal)";
    }
    svg_path.style.strokeWidth=line_width;
    var hasBeginArrows=options.hasBeginArrows;
    if(line.hasBeginArrows!=undefined)hasBeginArrows=line.hasBeginArrows;
    var hasEndArrows=options.hasEndArrows;
    if(line.hasEndArrows!=undefined) hasEndArrows=line.hasEndArrows;

    if(hasBeginArrows){
      svg_path.setAttribute("marker-start","url(#begin_arrow)")
    }
    if(hasEndArrows){
      svg_path.setAttribute("marker-end","url(#end_arrow)")
    }
    return svg_path;
  }

  function findChildElemnets(parent,childrenNameOrIdOrClass){
    var elements =[]
    var nameOrIdOrClass ='';
    var isId=false;
    var isClass=false;
    if(childrenNameOrIdOrClass[0]=="#"){
      nameOrIdOrClass=childrenNameOrIdOrClass.substring(1);
      isId=true;
    }
    if(childrenNameOrIdOrClass[0]=="."){
      nameOrIdOrClass=childrenNameOrIdOrClass.substring(1);
      isClass=true;
    }
    for(let i=0;i<parent.children.length;i++){
      const element=parent.children[i];
      if(isId){
        if(element.id==nameOrIdOrClass) elements.push(element);
      }else if(isClass){
        if(element.classList.contains(nameOrIdOrClass)) elements.push(element);
      }else{
        if(element.tagName==nameOrIdOrClass) elements.push(element);
      }
    }
    return elements;
  }

  function removeChildrenElements(parent,childrenNameOrId){
    findChildElemnets(parent,childrenNameOrId).forEach(element=>{
      parent.removeChild(element);
    });
  }
})();